home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MIDICraft's MIDINET CD-ROM
/
MIDICraft's MIDINET CD-ROM.iso
/
DOSUTILS
/
TXT2MIDI.DOC
< prev
next >
Wrap
Text File
|
1996-09-22
|
17KB
|
439 lines
******************************
TXT2MIDI v1.5
text mnemonics to midi binaries
by Guenter Nagler
1995
(gnagler@ihm.tu-graz.ac.at)
******************************
[0] FEATURES
+ compiles text into midi
+ modify existing midi files with help of MIDI2TXT
+ can be used to add text to midi files (copyright notice, lyric, ...)
+ copy and loop patterns
+ checks tact positions (marked as ".")
+ named GM-program names
+ additional text commands for Korg i2/i3 (e.g. bankdrum)
+ C-like comments // and /* ... */
+ mute and solo some channels
+ handles format 0 (all channels in a track) and format 1 midi files
(seperate tracks)
+ tempo can be specified midi like (ticks/minute) or in beats/minute
+ sysex events (including GMReset, GSReset, GSExit)
+ meta events (popular or unknown events)
+ direct events (midi command bytes)
+ compressing output by ommiting redunant midi command bytes
[1] BACKGROUND
After writing the pendant MIDI2TXT program it was obvious to program
a compiler to translate the text back to a midi binary. I used it to sequence
some music titles. When I bought my music workstation (including a more
powerful sequencer) my use of MIDI2TXT/TXT2MIDI changed into an
updating environment to make less compatible midi files full compatible.
Another use possibility came up when I copied some excellent midi
binaries from news://alt.binaries.sounds.midi . I converted one with
MIDI2TXT into text, commented all commands that played notes in leading
track and converted it back into another midi file (TXT2MIDI). The new
midi file played the full background of the music while I was able to
learn playing the lead voice for my own pleasure.
[2] FILES DESCRIPTION
TXT2MIDI.EXE.........compiler
TXT2MIDI.DOC.........this file, showing usage of TXT2MIDI.EXE
MIDILEX.L............LEX source code for text to midi
LEXYY.C..............output of flex compiling MIDILEX.L
TXT2MIDI.Y...........YACC source code for text to midi
TXT2MIDI.H...........output of byacc compiling TXT2MIDI.Y
TXT2MIDI.C...........output of byacc compiling TXT2MIDI.Y
MIDIREAD.CPP.........reading and writing midi binaries.
MIDIREAD.HPP.........prototypes for declarations in MIDIREAD.CPP
TXT2MIDI.MAK.........make file for project
TXT2MIDI.CFG.........compiler options for make
TXT2MIDI.PRJ.........project for borland c++ compilers
only TXT2MIDI.EXE is required to run program
[3] COPYRIGHT
TXT2MIDI (c) 1995 was created by Guenter Nagler.
TXT2MIDI is free and may be used as you wish with this one exception:
You may NOT charge any fee or derive any profit for distribution
of TXT2MIDI. Thus, you may NOT sell or bundle TXT2MIDI with any
product in a retail environment (shareware disk distribution, CD-ROM,
etc.) without permission of the author.
You may give TXT2MIDI to your friends, upload it to a BBS, or ftp it to
another internet site, as long as you don't charge anything for it.
Please send me a notice if you locate the program on a public BBS.
[4] DISCLAIMER
TXT2MIDI was designed to compile text file that are generated by
MIDI2TXT. So I give no guarantees of the compiler results, especially
with text files that are not generated by MIDI2TXT.
If you create an error free text file that can not be compiled
correctly, please send a sample file to gnagler@ihm.tu-graz.ac.at .
Use TXT2MIDI at your own risk. Anything you do with TXT2MIDI is your
responsibility, and not the author's. Any damage caused to any person,
computer, software, hardware, company, or business by running TXT2MIDI
is your responsibility, and the author will not be liable.
If you don't understand these terms, or are not sure of something, or
are afraid something bad might come of using TXT2MIDI, don't use it!
You are here forewarned.
[5] INSTALLATION
[MSDOS]
Simply copy TXT2MIDI.EXE in a directory that is in your path.
[UNIX]
compile sources with your C++ compiler (e.g. GNU Compiler g++):
g++ -o txt2midi txt2midi.c midiread.cpp lexyy.c
Hint: Force your compiler to compile all files C++ (and not C)!
If your compiler won't compile *.c as C++ then rename them to
*.cpp or *.C!
and run program
$ txt2midi
[6] USAGE
usage: TXT2MIDI textfile.txt midifile.mid
TXT2MIDI has no options and translates the textfile.txt which contains
a text representation of a midi file into binary.mid that should contain
a valid midi file if the compiler does not complain about errors or warnings.
Warning:
Do not expect that MIDI2TXT + TXT2MIDI will produce a copy of the original
file! MIDI allows to encode its commands in different ways without
changing the semantic of the notes (It is allowed to compress the
midi file by ommiting redunant command bytes, but it is no duty).
[7] GRAMMAR
Extended BNF rules:
-----------------------------------
symbol ::= expr ; rule for symbol
expr can be:
expr* optional list of expr's
expr+ repetition of expr's (at least 1)
[expr] optional expr (0 or 1 occurence)
expr1 expr2 ... exprN sequence of expr1 ... exprN (in this order)
expr1|expr2|...|exprN alternatives between expr1...exprN (choose one)
(expr) expr itself for grouping (e.g. ("+"|"-")*
"mthd" "(" keywords and operators (case sensitive, use
without " characters)
// text comment until next line
literal ::= characters enclosed in "..." e.g. "Track 1"
(special characters can be escaped by preceding \
e.g. "\"" is " character itself
lexical symbols (in E-BNF):
---------------------------------------
digit ::= "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9" ;
hexdigit ::= digit|"A"|"B"|"C"|"D"|"E"|"F"|"a"|"b"|"c"|"d"|"e"|"f" ;
decnumber ::= digit+ ;
hexnumber ::= "0" ("x"|"X") hexdigit+
| "$" hexdigit+
;
number ::= decnumber | hexnumber ;
floatnumber ::= decnumber | decnumber "." decnumber ;
notekey ::= "C"|"D"|"E"|"F"|"G"|"A"|"H"|"B"
| "c"|"d"|"e"|"f"|"g"|"a"|"h"|"b" ;
// notekey "h" used in German language is equal to
// notekey "b"
notename ::= notekey ["#" | "is" | "b" | "es"] decnumber ;
// only legal notes as known in music theory are allowed
// suffixes "is" and "es" are used in German language
// "is" is equal to "#"
// "es" is equal to "b"
// exceptions rules (in German language):
// As is equal to Ab
// Es is equal to Eb
// Use F instead of Eis
// Use C instead of His
// Use As instead of Aes
// Use Es instead of Ees
// Use H instead of Ces
// Use E instead of Fes
note ::= notename | number ;
programname ::=
// korg i2/i3 only:
"Dr1"|"Dr2"|"Dr3"|"Dr4"|"Dr5"|"Dr6"|"Dr7"|"Dr8"|
// general midi programs:
"Piano"| "BritePiano"| "HammerPiano"| "HonkeyTonk"| "NewTines"| "DigiPiano"| "Harpsicord"| "Clav"|
"Celesta"| "Glocken"| "MusicBox"| "Vibes"| "Marimba"| "Xylophon"| "Tubular"| "Santur"|
"FullOrgan"| "PercOrgan"| "BX-3Organ"| "ChurchPipe"| "Positive"| "Musette"| "Harmonica"| "Tango"|
"ClassicGtr"| "A.Guitar"| "JazzGuitar"| "CleanGtr"| "MuteGuitar"| "OverDrive"| "DistGuitar"| "RockMonics"|
"JazzBass"| "DeepBass"| "PickBass"| "FretLess"| "SlapBass1"| "SlapBass2"| "SynthBass1"| "SynthBass2"|
"Violin"| "Viola"| "Cello"| "ContraBass"| "TremoloStr"| "Pizzicato"| "Harp"| "Timpani"|
"Marcato"| "SlowString"| "AnalogPad"| "StringPad"| "Choir"| "DooVoice"| "Voices"| "OrchHit"|
"Trumpet"| "Trombone"| "Tuba"| "MutedTrumpet"| "FrenchHorn"| "Brass"| "SynBrass1"| "SynBrass2"|
"SopranoSax"| "AltoSax"| "TenorSax"| "BariSax"| "SweetOboe"| "EnglishHorn"| "BasoonOboe"| "Clarinet"|
"Piccolo"| "Flute"| "Recorder"| "PanFlute"| "Bottle"| "Shakuhachi"|"Whistle"| "Ocarina"|
"SquareWave"| "SawWave"| "SynCalinope"| "SynChiff"| "Charang"| "AirChorus"| "Rezzo4ths"| "Bass&Lead"|
"Fantasia"| "WarmPad"| "PolyPad"| "GhostPad"| "BowedGlas"| "MetalPad"| "HaloPad"| "Sweep"|
"IceRain"| "SoundTrack"| "Crystal"| "Atmosphere"| "Brightness"| "Goblin"| "EchoDrop"| "StarTheme"|
"Sitar"| "Banjo"| "Shamisen"| "Koto"| "Kalimba"|"Scotland"|"Fiddle"| "Shanai"|
"MetalBell"| "Agogo"| "SteelDrums"| "Woodblock"| "Taiko"| "Tom"| "SynthTom"| "RevCymbal"|
"FretNoise"| "NoiseChiff"| "Seashore"| "Birds"| "Telephone"| "Helicopter"| "Stadium!!"| "GunShot"
;
Grammar in extended BNF
-----------------------------------
midifile ::= midisong
;
midisong ::= songoption* midihead songoption* miditrack+
;
songoption ::= "mute" channel+ // ignore these channels
| "solo" channel+ // use these channels only
;
channel ::= number // only 1-16 are valid channels
; // channel 10 should be used for drums
midihead ::= "mthd" [version] [unit] "end" "mthd"
;
version ::= "version" number // default version: 1
// currently only versions 0-2 are allowed
// version 0 = single multichannel track
// version 1 = some singlechannel tracks playing together
// version 2 = some multichannel tracks playing one after one
unit ::= "unit" number // default unit: 192
;
miditrack ::= "mtrk" [ "(" channel ")" ]
event*
"end" "mtrk"
;
event ::= [ "[" channel "]" ] midievent
| "velocyon" number // default is 127
| "velocyoff" number // default is 0
| duration sep // pause: delay between events
| "print" sep
| "transpose" ["+"|"-"] number sep
| sep
| "copy" "part" literal ;
| "part" literal
event*
"end" "part" literal
;
| "loop" number
event*
"end" "loop"
;
sep ::= ";" | "." ; // "." checks of end of tact
midievent ::=
"seqnumber" number
| "text" literal
| "copyright" literal
| "trackname" literal
| "instrument" literal
| "lyric" literal
| "prefixchannel" channel // following sysex or meta event is applied to this channel
| "prefixport" number // following sysex or meta event is applied to this port
| "smpteofs" number ":" number ":" number ":" number ":" number
// SMPTE offset hour:minute:second:frame:fractional_frame
| "tact" number "/" number number number // tactnom / (2 ^^ tactdenom) clicks/beat 32th/beat
| "tempo" number // microseconds per quarternote
| "beats" floatnumber // same as 60.000.000/tempo
// quarternotes per minute
| "key" literal // literal must contain a valid key:
// "Cmin" "Cmaj" "1bmin" "1bmaj" ... "7bmaj" ... "7#min" "7#maj"
| "event"
bytes
"end" "event"
| "metaevent" number "(" number ")" // a) metaevent nr. 0-127 b) length
bytes // length (number) must match number of bytes!
"end" "metaevent" // metaevents are 0xff-codes
| "sysevent" "(" number ")" // number of sysex data bytes
bytes // length (number) must match number of bytes!
"end" "sysevent" // sysevents are 0xf0-codes
// end sysevent code 0xf7 is appended automatically!
| "gmreset" // common sysex command to set GM mode on
| "gsreset" // common sysex command to set GS mode on (mainly used for Roland, Yamaha)
| "gsenter" // same as command gsreset
| "gsexit" // common sysex command to set GS mode off (mainly used for Roland, Yamaha)
| "program" (programname | number | ("A"|"B"|"C"|"D") number
| "control" number number
| "hbank" number
| "lbank" number
| "banka"
| "bankb"
| "bankc"
| "bankd"
| "bankdrum" // bank*: korg i2/i3 only!
| "balance" ("left" | "right" | number)
// number is a value between 0 and 127: 0 is left and 127 is right
| "hold" ("on" | "off" | number)
| "reverb" number
| "chorus" number
| "brightness" number
| "expression" number
| "pitchmodulation" number
| "wheel" number
| "breath" number
| "foot" number
| "portamentotime" number
| "portamento" number
| "data" number
| "volume" number
| "sustain" number
| "sostenuto" number
| "softpedal" number
| "datainc" number
| "datadec" number
| "highRPN" number
| "lowRPN" number
| "pitchbendrange" number
| "localon"
| "localoff"
| "silent"
| "allnotesoff"
| "omnioff"
| "omnion"
| "monoon"
| "polyon"
| "songpos" number number
| "songselect" number
| "tunerequest"
| "timingclock"
| "start"
| "continue"
| "stop"
| "activesensing"
| "polyaftertouch" note number
| "aftertouch" number
| "pitchbend" number
| notename duration number sep
| "+" notename (number|"velocyon") sep
| "-" notename (number|"velocyoff) sep
| "+" number // note on
| "-" number // note off
;
duration ::=
number // units as defined in header
| number "/" number (tact units, e.g. 3/4)
;
program ::= number | programname ;
bytes ::= (number|literal)+ ;
A midi file format documentation can be downloaded by anonymous ftp from
location:
ftp://ftp.cs.ruu.nl/pub/MIDI/DOC
Document "midifile" explains all terms used in this grammar.
[8] SAMPLE TEXT
// itsasin.mid // comment until end of line
mthd // header
// 1 song
// 17 tracks
unit 120 // is 1/4 // 120 ticks = 1/4 tact
end mthd // end header
mtrk
tact 4 / 4 24 8 // typical 4/4 Tact
metaevent 89(2) $00 $00 end metaevent
beats 128 // 128 beats/min (quarter notes)
4/4. // tact 1
metaevent 6(26) "It's a sin. Pet Shop Boys." end metaevent
end mtrk
mtrk($1) // track with channel (hex) 1
metaevent 33(1) $00 end metaevent
trackname "String Lead"
program AnalogPad
volume 119
4/4. // tact 1 // end of tact 1
4/4. // tact 2
4/4. // tact 3
4/4. // tact 4
+d#5 $40; // note on with velocity $40 (hex 40 = 64 dec)
4/4. // tact 5
-d#5 $00; // note off
+d#6 $50; // ; is note separator . is tact separator (optional)
+d#5 $50;
4/4. // tact 6 // duration in tact units
+c5 $50;
228;-c5 $00; // duration in tick units
-d#5 $00;
-d#6 $00;
// rest of midi is cut
end mtrk
[9] SUGGESTIONS / COMMENTS / BUG REPORTS / QUESTIONS
WWW: http://hgiicm.tu-graz.ac.at/Cpub
contains all my dos/unix midi programs
EMAIL: gnagler@ihm.tu-graz.ac.at
[10] CHANGES
v1.0 to v1.1:
* beats floating-point-number is now allowed (e.g. beats 65.5)
(suggestion by: djeff@cobra.jpl.nasa.gov)
* optional version field in header (default: is version 1)
* portability changes for Unix compatibility
- no stricmp/strnicmp calls
- no dos.h if not compiling under __MSDOS__
v1.1 to v1.2:
* keywords now must be followed by whitespace that they are recognized as
keywords (former: "Trumpets" was separated into words "Trumpet" and "s").
* invalid characters in the source text now produce "invalid character"
error message instead of adding it to the output midi file (major bug,
produced invalid midi file).
* uses less compression (only note on/off commands are compressed,
i.e. collects a sequence of these commands to one command)
to produce safer compatible output for some sequencers.
* added new keywords: GMReset, GSReset, GSEnter, GSExit
v1.2 to v1.3:
* added meta events mnemonics prefixchannel and prefixport
* added option -version
* fixed bug that failed to convert note names C-1 .. B-1 into 0..11
* added documentation for using German language note names
v1.3 to v1.4:
* fixed bug occuring in use of solo
where last used channel in a multi channel track is muted
(didn't close the track and caused invalid midi file)
* error added if using multiple channels in single channel tracks
(e.g. track reserved channel 10 and uses other too)
* fixed bug when using solo,mute in multi channel track:
illegal write of delta time for command on mute channel
* added control commands highRPN and lowRPN and pitchbendrange
v1.4 to v1.5:
* Warning if channel of a track is not initialized
* fixed bug that disabled "program number" command
for certain numbers (e.g. 0)
* forbidding channel numbers out of range 1-16
* bug fixed in literals converting characters written hex (e.g. \x82 )
* added command XGreset